
using System;
using System.Runtime.InteropServices;
using System.Text;
using UnityEngine;

public class GameApp : MonoBehaviour
{
    // C/C++ 端使用的log函数
    // 需要定义一个委托，传递给C/C++端
    public delegate void CLog(IntPtr log);
    
    private void Awake()
    {
        Debug.Log("awake");

        Debug.Log("set CLog func");
        CLog cLog = CLogInstance;
        DllMgr.SetUnityLogFunc(cLog);
        
        Debug.Log(DllMgr.Add(1, 3));
        Debug.Log(DllMgr.Minus(1, 3));
        Debug.Log(DllMgr.Multiply(1, 3));
        Debug.Log(DllMgr.Divide(1, 3));

        UpperContent("hello world,;");
    }

    void UpperContent(string content)
    {
        // Marshal.StringToHGlobalUni 将unicode 字符串分配到未托管内存，并且返回内存指针
        
        // 用于在未托管内存中分配足够的空间来存储 Unicode 字符串，并将其内容复制到该内存中。
        IntPtr stringPtr = Marshal.StringToHGlobalUni(content);
        
        // 数据从C/C++到C#时问题不大，但是如果从C#到C/C++时一定要将数组先固化，然后再传递处理。
        DllMgr.Upper(stringPtr);

        string modifyStr = Marshal.PtrToStringUni(stringPtr);
        // 释放非托管内存
        Marshal.FreeHGlobal(stringPtr);
        
        Debug.Log(modifyStr);
    }
    
    // IntPtr 是 C# 中用于表示指针或句柄的类型。它是一个平台特定的整数类型，其大小足够大，
    // 以容纳指向任何数据的指针。IntPtr 主要用于与非托管代码进行交互，
    // 因为在托管环境中直接使用指针是不安全的。

    // C/C++ 端传递的需要是w_char类型，因为用的是PtrToStringUni函数
    void CLogInstance(IntPtr log)
    {
        string realLog = Marshal.PtrToStringAnsi(log);
        Debug.Log(realLog);
    }
}
